module pc(
    input clk,
    input reset,
    input [5:0] stall,
    input [63:0] b_j_pc,
    input pcsource,
    input [63:0] new_pc,
    input flush,
    input ret,
    input flush_if_id,
    input keep,

    output reg [63:0] o_inst_addr,
    output [63:0] o_badvaddr,
    output [63:0] o_excode,
    output o_except_ena
);

    always @(posedge clk) begin
        if(reset) begin
            o_inst_addr <= 64'h0000000080000000;
        end else if(flush | ret) begin
            o_inst_addr <= new_pc;
        end else if(keep) begin
            o_inst_addr <= o_inst_addr;
        end else if(stall[0] == 1'b0) begin
            if(pcsource) begin
                o_inst_addr <= b_j_pc;
            end else begin
                o_inst_addr <= o_inst_addr + 64'd4;
            end
        end
    end

    assign o_badvaddr = o_inst_addr[1:0] == 2'b00 ? 64'd0 : o_inst_addr;
    assign o_excode = o_inst_addr[1:0] == 2'b00 ? 64'd0 : {1'b0, 63'd0};
    assign o_except_ena = o_inst_addr[1:0] == 2'b00 ? 1'b0 : 1'b1;

endmodule
